package com.example.seakdreamandroid.accountInfo;

import android.animation.Animator;
import android.app.Activity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.PopupWindow;

import com.example.seakdreamandroid.R;

/**
 * 何鸿辉
 * 这个类是为了复用代码，实现在一个页面上从下方弹出伴随背景变暗效果的弹窗
 */
public class PopupAndDarkenWindow {
    private Activity activity;
    private Window window;
    private AnimUtil animUtil;
    private PopupWindow popupWindow;
    private View v;
    //标识弹窗状态，false表示弹出，true表示弹回
    private boolean bright = false;
    //标识是否开启从下方弹出的效果
    private boolean isPopup = true;
    //标识是否开启视野变暗的效果
    private boolean isDarken = true;
    //标识视野最后暗淡的程度，取值在0——1之间
    private float backgroundDarken = 0.5f;
    //标识视野变暗用时
    private int darkenDuration = 400;
    //弹出的视图的layout_width
    private int width = ViewGroup.LayoutParams.MATCH_PARENT;
    //弹出的视图的layout_height
    private int height = ViewGroup.LayoutParams.WRAP_CONTENT;
    private boolean isInit = false;
    //标识是否初始化，必须初始化才能调用popupWindow()方法
    private int layoutId;

    public PopupAndDarkenWindow(Activity activity, int layoutId) {
        this.activity = activity;
        this.layoutId = layoutId;
        this.window = activity.getWindow();
        v =  LayoutInflater.from(activity).inflate(layoutId, null);
    }

    public PopupAndDarkenWindow(Activity activity, int layoutId, int width, int height) {
        this.activity = activity;
        this.layoutId = layoutId;
        this.window = activity.getWindow();
        this.width = width;
        this.height = height;
        v =  LayoutInflater.from(activity).inflate(layoutId, null);
    }

    public PopupAndDarkenWindow setDarkenDuration(int darkenDuration) {
        checkIsInit();
        this.darkenDuration = darkenDuration;
        return this;
    }

    public PopupAndDarkenWindow setPopup(boolean popup) {
        checkIsInit();
        isPopup = popup;
        return this;
    }

    public PopupAndDarkenWindow setBackgroundDarken(float backgroundDarken) {
        checkIsInit();
        if(backgroundDarken<0)this.backgroundDarken = 0;
        else if(backgroundDarken>1)this.backgroundDarken = 1;
        else this.backgroundDarken = backgroundDarken;
        return this;
    }

    public PopupAndDarkenWindow setDarken(boolean darken) {
        checkIsInit();
        isDarken = darken;
        return this;
    }
    public PopupAndDarkenWindow setLayoutParam(int width,int height){
        checkIsInit();
        this.width = width;
        this.height = height;
        return this;
    }
    public PopupAndDarkenWindow setWidth(int width) {
        checkIsInit();
        this.width = width;
        return this;
    }

    public PopupAndDarkenWindow setHeight(int height) {
        checkIsInit();
        this.height = height;
        return this;
    }

    public PopupAndDarkenWindow setLayoutId(int layoutId) {
        checkIsInit();
        this.layoutId = layoutId;
        return this;
    }

    /**
     * 初始化方法，之前进行配置，之后使用
     */
    public void init(){
        isInit = true;
        if(isDarken)initAnimUtil();
        initPopupWindow(width,height);
    }

    /**
     * 设置背景透明度实现变暗效果
     * @param bgAlpha 透明度
     */
    private void backgroundAlpha(float bgAlpha) {
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.alpha = bgAlpha; //0.0-1.0
        window.setAttributes(lp);
        window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
    }

    private void initAnimUtil() {
        animUtil = new AnimUtil();
        animUtil.setValueAnimator(backgroundDarken, 1f, darkenDuration);
        animUtil.addUpdateListener(new AnimUtil.UpdateListener() {
            @Override
            public void progress(float progress) {
                //此处系统会根据上述三个值，计算每次回调的值是多少，我们根据这个值来改变透明度
                float bgAlpha = bright ? progress : (backgroundDarken + 1 - progress);
                backgroundAlpha(bgAlpha);//在此处改变背景
            }
        });
        animUtil.addEndListner(new AnimUtil.EndListener() {
            @Override
            public void endUpdate(Animator animator) {
                //在一次动画结束的时候，翻转状态
                bright = !bright;
            }
        });
    }


    private void initPopupWindow(int width,int height) {
        popupWindow = new PopupWindow(v, width, height);
        popupWindow.setFocusable(true);
        if(isPopup){
            popupWindow.setAnimationStyle(R.style.accountInfoAnimStyle);
        }
        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                toggleBright();
            }
        });

    }

    /**
     * 执行弹出时背景变暗的动画
     */
    private void toggleBright() {
        if(isDarken){
            animUtil.startAnimator();
        }else{
            if(!bright){
                backgroundAlpha(backgroundDarken);
            }else{
                backgroundAlpha(1.0f);
            }
            bright = !bright;
        }
    }

    /**
     * 设置弹出的窗口视图中的各种监听器，允许init()方法后设置
     * @param callBack 设置监听器的回调
     */
    public void setPopupViewListener(SetPopupViewListenerCallBack callBack) {
        if(callBack != null)callBack.setListener(v,this);
    }

    public void popupWindow() {
        checkNotInit();
        if(!popupWindow.isShowing()){
            popupWindow.showAtLocation(v, Gravity.BOTTOM,0,0);
            toggleBright();
        }

    }

    /**
     * 检查是否没有初始化
     */
    private void checkNotInit() {
        if(!isInit){
            throw new RuntimeException("还未初始化");
        }
    }

    /**
     * 检查是否已经初始化
     */
    private void checkIsInit(){
        if(isInit){
            throw new RuntimeException("已经初始化");
        }
    }

    public void dismiss(){
        checkNotInit();
        if(popupWindow.isShowing()){
            popupWindow.dismiss();
        }
    }
    public PopupWindow getPopupWindow(){
        return popupWindow;
    }

    public interface SetPopupViewListenerCallBack{
        public void setListener(View v,PopupAndDarkenWindow popupAndDarkenWindow);
    }
}
